package xin.fsqr520.project.util;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Redis 字符串操作工具类
 * 封装了常见字符串操作命令
 */
@Component
public class RedisStringUtil {

    private final ValueOperations<String, String> valueOperations;

    public RedisStringUtil(ValueOperations<String, String> valueOperations) {
        this.valueOperations = valueOperations;
    }

    /**
     * 设置字符串值（永久有效）
     *
     * @param key   键
     * @param value 值
     */
    public void set(String key, String value) {
        valueOperations.set(key, value);
    }

    /**
     * 设置带过期时间的字符串值
     *
     * @param key     键
     * @param value   值
     * @param timeout 过期时间
     * @param unit    时间单位
     */
    public void setWithExpire(String key, String value, long timeout, TimeUnit unit) {
        valueOperations.set(key, value, timeout, unit);
    }

    /**
     * 获取字符串值
     *
     * @param key 键
     * @return 对应的值，不存在时返回 null
     */
    public String get(String key) {
        return valueOperations.get(key);
    }

    /**
     * 安全获取字符串值（带默认值）
     *
     * @param key          键
     * @param defaultValue 默认值
     * @return 对应的值，不存在时返回默认值
     */
    public String getOrDefault(String key, String defaultValue) {
        String value = valueOperations.get(key);
        return value != null ? value : defaultValue;
    }

    /**
     * 设置值并返回旧值
     *
     * @param key   键
     * @param value 新值
     * @return 旧值，不存在时返回 null
     */
    public String getAndSet(String key, String value) {
        return valueOperations.getAndSet(key, value);
    }

    /**
     * 当键不存在时设置值
     *
     * @param key   键
     * @param value 值
     * @return 是否设置成功
     */
    public boolean setIfAbsent(String key, String value) {
        return Boolean.TRUE.equals(valueOperations.setIfAbsent(key, value));
    }

    /**
     * 当键不存在时设置带过期时间的值
     *
     * @param key     键
     * @param value   值
     * @param timeout 过期时间
     * @param unit    时间单位
     * @return 是否设置成功
     */
    public boolean setIfAbsentWithExpire(String key, String value, long timeout, TimeUnit unit) {
        return Boolean.TRUE.equals(valueOperations.setIfAbsent(key, value, timeout, unit));
    }

    /**
     * 删除键
     *
     * @param key 键
     * @return 是否删除成功
     */
    public boolean delete(String key) {
        return Boolean.TRUE.equals(valueOperations.getOperations().delete(key));
    }

    /**
     * 检查键是否存在
     *
     * @param key 键
     * @return 是否存在
     */
    public boolean exists(String key) {
        return Boolean.TRUE.equals(valueOperations.getOperations().hasKey(key));
    }

    /**
     * 获取键的剩余过期时间
     *
     * @param key  键
     * @param unit 时间单位
     * @return 剩余时间（单位取决于unit参数），键不存在返回 -2，永久有效返回 -1
     */
    public Long getExpire(String key, TimeUnit unit) {
        return valueOperations.getOperations().getExpire(key, unit);
    }

    /**
     * 设置键的过期时间
     *
     * @param key     键
     * @param timeout 过期时间
     * @param unit    时间单位
     * @return 是否设置成功
     */
    public boolean expire(String key, long timeout, TimeUnit unit) {
        return Boolean.TRUE.equals(valueOperations.getOperations().expire(key, timeout, unit));
    }
}